/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/* 
 * File:   CSwitchManager.cpp
 * Author: Administrator
 * 
 * Created on 2017年11月22日, 下午6:02
 */

#include "CSwitchManager.h"
#include "PublicMySql.h"
#include "WorkSnmpApi.h"
#include "WorkPingApi.h"
#include "PublicLog.h"
#include "Common.h"
#include "SnmpApi.h"
CSwitchManager::CSwitchManager(){
}

CSwitchManager::~CSwitchManager(){
	MAPSWITCHLIST::iterator it=m_iplistinfo.begin();
	while(it!=m_iplistinfo.end()){
		delete it->second;
		it++;
	}
}
void CSwitchManager::UpdateSwitchIPLIST(){
	MYSQL*mysql=OpenMySQL(MYSQL_BASE);
	const char*sql="SELECT`IP`,`community`FROM`sysinfo`WHERE`enable`<>0;";
	my_ulonglong num=0;
	m_iplist.clear();
	MYSQL_RES*res=RunMySQLGetRes(mysql,sql,num);
	if(res){
		MYSQL_ROW row;
		while((row=MySQLFetchRow(res))!=NULL){
			if((row[0]!=NULL)&&(IsIPV4(row[0])==1)){
				m_iplist.insert(row[0]);
				if((row[1]!=NULL)&&(row[1][0]!='\0')){
					UpdateSnmpCommunity(row[0],row[1]);
				}
			}
		}
		INFO("成功获取%zd个IP",m_iplist.size());
	}else{
		WRONG("IP列表获取失败");
	}
	FreeMySQLRes(res);
	CloseMySQL(mysql);
}
void CSwitchManager::UpdateSwitchSysInfo(){
	SNMPFLAG flag=InitSnmpFlag();
	strcpy(flag.Communtiy,g_sysconf.community);
	MAPSTRINGLIST CommunityList= GetSnmpCommunity();
	m_switchinfo=GetSnmpInfoByIPList(m_iplist,flag,CommunityList);
#if USE_PUBLIC_PING	
	PINGFLAG pingflag=InitPingFlag();
	pingflag.PingTimes=5;
	MAPLOSSINFO resultping=GetLossInfoByIPList(m_iplist,pingflag);
#endif	
	MYSQL*mysql=OpenMySQL(MYSQL_BASE);
	const char*Head="INSERT INTO`sysinfo`(`IP`,`ifNumber`,`sysObjectID`,"
	"`softVersion`,`ProductName`,`Manufacturer`,`sysName`,"
	"`sysDescr`,`sysContact`,`sysLocation`,"
	"`sysServices`,`ipForwarding`,`ipv6Forwarding`,"
	"`ipCidrRouteNumber`,`inetCidrRouteNumber`,`ipv6RouteNumber`,"
	"`sysUpTimeInstance`,`snmptime`,`pingtime`)VALUES";
	const char*End="ON DUPLICATE KEY UPDATE"
"`ifNumber`=VALUES(`ifNumber`),"
"`sysObjectID`=VALUES(`sysObjectID`),"
"`softVersion`=VALUES(`softVersion`),"
"`ProductName`=VALUES(`ProductName`),"
"`Manufacturer`=VALUES(`Manufacturer`),"
"`sysName`=VALUES(`sysName`),"
"`sysDescr`=VALUES(`sysDescr`),"
"`sysContact`=VALUES(`sysContact`),"
"`sysLocation`=VALUES(`sysLocation`),"
"`sysServices`=VALUES(`sysServices`),"
"`ipForwarding`=VALUES(`ipForwarding`),"
"`ipv6Forwarding`=VALUES(`ipv6Forwarding`),"
"`ipCidrRouteNumber`=VALUES(`ipCidrRouteNumber`),"
"`inetCidrRouteNumber`=VALUES(`inetCidrRouteNumber`),"
"`ipv6RouteNumber`=VALUES(`ipv6RouteNumber`),"
"`sysUpTimeInstance`=VALUES(`sysUpTimeInstance`),"
"`snmptime`=VALUES(`snmptime`),"
"`pingtime`=VALUES(`pingtime`);";
	int Count=0;
	std::string sqlbuff;
	m_alivelist.clear();
	MAPSNMPSYSPACKET::iterator it=m_switchinfo.begin();
	while(it!=m_switchinfo.end()){
		int ping=0;
#if USE_PUBLIC_PING		
		do{
			MAPLOSSINFO::iterator it2=resultping.find(it->first);
			if(it2!=resultping.end()){
				ping=it2->second.pingavg;
			}
		}while(0);
#endif		
		if(it->second.snmptime>0){
			m_alivelist.insert(it->first);
		}
		char tmp[2048]={0};
		sprintf(tmp,"('%s',%u,'%s','%s','%s','%s','%s','%s','%s','%s',%u,%u,%u,%u,%u,%u,%u,%d,%d)",
			it->first.c_str(),it->second.ifNumber,it->second.sysObjectID,
			it->second.softVersion,it->second.ProductName,it->second.Manufacturer,it->second.sysName,
			it->second.sysDescr,it->second.sysContact,it->second.sysLocation,
			it->second.sysServices,it->second.ipForwarding,it->second.ipv6Forwarding,
			it->second.ipCidrRouteNumber,it->second.inetCidrRouteNumber,it->second.ipv6RouteNumber,
			it->second.sysUpTimeInstance,
			it->second.snmptime,ping);
		if(Count==0){
			sqlbuff=Head;
		}else{
			sqlbuff+=",";
		}
		sqlbuff+=tmp;
		Count++;
		if(Count>500){
			sqlbuff+=End;
			RunMySQL(mysql,sqlbuff.c_str());
			Count=0;
		}
		//INFO("%s %s %s %d %d",it->first.c_str(),it->second.sysName,it->second.ProductName,it->second.snmptime,ping);
		it++;
	}
	if(Count>0){
		sqlbuff+=End;
		RunMySQL(mysql,sqlbuff.c_str());
		Count=0;
	}
	CloseMySQL(mysql);
}
void*CSwitchManagerThread(void*data){
	CSwitchManager*ptr=(CSwitchManager*)data;
	ptr->RunOnce();
	sleep(1);
}
void*CSwitchManagerThreadData(void*data){
	CSwitchManager*ptr=(CSwitchManager*)data;
	ptr->RunOnceData();
	sleep(1);
}
void CSwitchManager::UpdateSwitchifTable(){
	CMultiThreadManager threadmanager;
	MakeList();
	threadmanager.StartWorkThread(CSwitchManagerThread,this,g_sysconf.threads,"ifTableCollect");
	while(IsListEmpty()==false){
		sleep(1);
	}
	threadmanager.StopWorkThread();	
}
void CSwitchManager::UpdateSwitchDataTable(){
	CMultiThreadManager threadmanager;
	MakeList();
	threadmanager.StartWorkThread(CSwitchManagerThreadData,this,g_sysconf.threads,"DataTableCollect");
	while(IsListEmpty()==false){
		sleep(1);
	}
	threadmanager.StopWorkThread();	
}
void CSwitchManager::RunOnce(){
	std::string ip=m_ranlist.PopList();
	if(ip!=""){
		m_Mutex.Lock();
		MAPSWITCHLIST::iterator it2=m_iplistinfo.find(ip.c_str());
		if(it2==m_iplistinfo.end()){
			CSwitchifTable*tmp=new CSwitchifTable(ip.c_str());
			m_iplistinfo.insert(std::pair<std::string,CSwitchifTable*>(ip.c_str(),tmp));
			it2=m_iplistinfo.find(ip.c_str());
		}
		m_Mutex.UnLock();
		if(it2!=m_iplistinfo.end()){
			it2->second->UpDateifTable();
		}else{
			WRONG("Try GET %s ifTable Failed",ip.c_str());
		}
	}
}
void CSwitchManager::RunOnceData(){
	std::string ip=m_ranlist.PopList();
	if(ip!=""){
		CSwitchData*tmp=new CSwitchData(ip);
		m_Mutex.Lock();
		MAPSNMPSYSPACKET::iterator it=m_switchinfo.find(ip);
		if(it!=m_switchinfo.end()){
			tmp->UpdateSwitchSysInfo(it->second);
		}
		m_Mutex.UnLock();
		tmp->UpDateSwitchData();
		tmp->UpLoadToServer();
		delete tmp;
	}
}
//构建队列
bool CSwitchManager::MakeList(){
	m_ranlist.InsertSetList(m_alivelist);
	return true;
}
//判断队列是否为空
bool CSwitchManager::IsListEmpty(){
	return m_ranlist.Empty();
}
#if 0	
void CSwitchManager::UpdateSwitchifFlow(time_t starttime,time_t endtime){
	SETIPLIST::iterator it=m_iplist.begin();
	while(it!=m_iplist.end()){
		CSwitchifTable tmp(it->c_str());
		tmp.UpDateifFlowAll(starttime,endtime);
		it++;
	}
}
#endif
MAPSNMPSYSPACKET CSwitchManager::GetAllSwitchInfo(){
	MAPSNMPSYSPACKET result;
	MYSQL*mysql=OpenMySQL(MYSQL_BASE);
	const char*sql="SELECT`IP`,`sysName`,`ifNumber`,`sysDescr`FROM`sysinfo`WHERE`ifNumber`>0;";
	my_ulonglong num=0;
	MYSQL_RES*res=RunMySQLGetRes(mysql,sql,num);
	if(res){
		MYSQL_ROW row;
		while((row=MySQLFetchRow(res))!=NULL){
			SNMPSYSPACKET tmp={0};
			strcpy(tmp.sysName,row[1]);
			tmp.ifNumber=atoi(row[2]);
			strcpy(tmp.sysDescr,row[3]);
			result.insert(std::pair<std::string,SNMPSYSPACKET>(row[0],tmp));
		}
		INFO("成功获取%zd个IP",result.size());
	}else{
		WRONG("IP列表获取失败");
	}
	FreeMySQLRes(res);
	CloseMySQL(mysql);
	return result;
}